package com.csii.activiti.server.core.utils;

import com.csii.activiti.server.core.entity.ActFlowCondition;
import com.csii.activiti.server.core.entity.ActFlowConditionGroup;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiPredicate;

public class VerifyConditionUtils {
    private static Map<String,BiPredicate<ActFlowCondition,Map<String,Object>>> conditionPredicateMap = new HashMap<>();

    private final static String EQ = "=";
    private final static String DEQ = "==";
    private final static String NE = "!=";
    private final static String GE = ">=";
    private final static String GT = ">";
    private final static String LE = "<=";
    private final static String LT = "<";
    static {
        //等于
        BiPredicate<ActFlowCondition,Map<String,Object>> eqPredicate = (condition,formData) -> {

            Object val = formData.get(condition.getFormElementKey());
            if (val == null){
                return false;
            }
            return condition.getValue().equals(val);
        };
        conditionPredicateMap.put(EQ,eqPredicate);
        conditionPredicateMap.put(DEQ,eqPredicate);
        //不等于
        BiPredicate<ActFlowCondition,Map<String,Object>> nePredicate = (condition,formData) -> {

            Object val = formData.get(condition.getFormElementKey());
            if (val == null){
                return false;
            }
            return !condition.getValue().equals(val);
        };
        conditionPredicateMap.put(NE,nePredicate);
        //大于等于
        BiPredicate<ActFlowCondition,Map<String,Object>> gePredicate = (condition,formData) -> {

            Object val = formData.get(condition.getFormElementKey());
            if (val == null){
                return false;
            }
            Double v1 = Double.parseDouble(val.toString());
            Double v2 = Double.parseDouble(condition.getValue());
            return v1.compareTo(v2) >= 0;
        };
        conditionPredicateMap.put(GE,gePredicate);
        //大于等于
        BiPredicate<ActFlowCondition,Map<String,Object>> gtPredicate = (condition,formData) -> {

            Object val = formData.get(condition.getFormElementKey());
            if (val == null){
                return false;
            }
            Double v1 = Double.parseDouble(val.toString());
            Double v2 = Double.parseDouble(condition.getValue());
            return v1.compareTo(v2) > 0;
        };
        conditionPredicateMap.put(GT,gtPredicate);
        //小于等于
        BiPredicate<ActFlowCondition,Map<String,Object>> lePredicate = (condition,formData) -> {

            Object val = formData.get(condition.getFormElementKey());
            if (val == null){
                return false;
            }
            Double v1 = Double.parseDouble(val.toString());
            Double v2 = Double.parseDouble(condition.getValue());
            return v1.compareTo(v2) <= 0;
        };
        conditionPredicateMap.put(LE,lePredicate);
        //小于
        BiPredicate<ActFlowCondition,Map<String,Object>> ltPredicate = (condition,formData) -> {

            Object val = formData.get(condition.getFormElementKey());
            if (val == null){
                return false;
            }
            Double v1 = Double.parseDouble(val.toString());
            Double v2 = Double.parseDouble(condition.getValue());
            return v1.compareTo(v2) < 0;
        };
        conditionPredicateMap.put(LT,ltPredicate);
    }

    public static boolean verifyConditionGroups(List<ActFlowConditionGroup> conditionGroups, Map<String,Object> formData){
        if (conditionGroups == null){
            return true;
        }
        for (ActFlowConditionGroup conditionGroup : conditionGroups) {
            if (verifyConditions(conditionGroup.getConditions(),formData)){
                return true;
            }
        }
        return false;
    }


    public static boolean verifyConditions(List<ActFlowCondition> conditions, Map<String,Object> formData){
        for (ActFlowCondition condition : conditions) {
            BiPredicate<ActFlowCondition, Map<String, Object>> actFlowConditionMapBiPredicate = conditionPredicateMap.get(condition.getOperation());
            if(!actFlowConditionMapBiPredicate.test(condition,formData)){
                return false;
            }
        }
        return true;
    }

}
